<?

/* Грузим функции Артема */
require_once '__amixen/functions.general.php';
/*
echo '<hr>';
echo '$_SERVER[HTTP_HOST]= '.$_SERVER['HTTP_HOST'].'<br>';
echo '$_SERVER[DOCUMENT_ROOT]= '.$_SERVER['DOCUMENT_ROOT'].'<br>';
echo '$_SERVER[REQUEST_URI]= '.$_SERVER['REQUEST_URI'].'<br>';
echo '$_SERVER[HTTP_REFERER]= '.$_SERVER['HTTP_REFERER'].'<br>';
echo '<hr>';
/*
echo '$CFG[domain]= '.$CFG['domain'].'<BR>';
//echo '$CFG[subdomain]= '.$CFG['subdomain'].'<BR>';
echo '$CFG[host]= '.$CFG['host'].'<BR>';
echo '$CFG[host_full]= '.$CFG['host_full'].'<BR>';
//echo '$CFG[host_admin_]= '.$CFG['host_admin_'].'<BR>';
//echo '$CFG[host_full_admin_]= '.$CFG['host_full_admin_'].'<BR>';
//echo '$CFG[host_original]= '.$CFG['host_original'].'<BR>';
echo '$CFG[path]= '.$CFG['path'].'<BR>';
//echo '$CFG[path_original]= '.$CFG['path_original'].'<BR>';
echo '$CFG[path_general]= '.$CFG['path_general'].'<BR>';
echo '<hr>';
*/


//	********************************
//	SbSE engine v0.9.50 / 2012.04.27
//	********************************
//	what's new:
// + killmeta DAO. No need of 'ON DELETE CASCADE' anymore.
// + log4 support
// + additional page buffering made for ugly IE script loading workaround
// + context collecting
// * potentially XSS in language switcher fixed
// + time measuring
// + memcached
// * detect and get an appropriate template when no database connection established
// * URL processing upgraded
// * language processing fixes
// + site root dir detection for cron scripts
// + manual language detection in the URL
// + now loads db interface directly
// + $HEAD for the head meta tags support
// + separate linked and inline scripts in the $SCRIPT
// + isAdminPage @ $CONTEXT
// * META is available in routers
// * ip address processing fixed
// * remove_param can remove comma separated list of params
// + fetch localized page name
// * permitted
// * title generation just before the show
// + capture debug output up to the moment we can determine if we have rights to see it
// * new security logic and fixes
// + added $CONTEXT['format'] contains 'html' or 'xml'
// * strip deprecated functions 'ereg' and 'split' from the code for the PHP 5.3 compatibility
// + templates localization & routing
// + global $SCRIPT array for the Js scripts
// * id as param can consists of anything after the number
// * xml processing fix
// * logout fix
// + include bits' init before template's init
// + collects BITS from config & meta
// * now checks PATH_INFO, ORIG_PATH_INFO & REQUEST_URI
// + $STACK added
// * ID was moved to the last position (before anchor) in generated URLs
// * some fixes to lang processing
define('ENGINE_VERSION', '0.9.50');

$DATA = array('e-time-start' => microtime(true), 'e-time' => array());

function timesnap($msg) {
	$GLOBALS['DATA']['e-time'][] = array(
		'time' => round((microtime(true) - $GLOBALS['DATA']['e-time-start']) * 1000, 1),
		'msg' => $msg);
}

function timedrop() {
/*
	$_rec = array('page_id' => $GLOBALS['DATA']['page']['id'], 'url' => $GLOBALS['CONTEXT']['rawUrl'], 't' => parse_now());
	$i = 0; while(($t = array_shift($GLOBALS['DATA']['e-time'])) && (++$i <= 5)) {
		$_rec['n0'.$i] = $t['msg'];
		$_rec['t0'.$i] = $t['time'];
	}
	dataset('db_insert', 'stat', $_rec);
*/
	$t = array();
	if (getdata('t') == 't') {
		foreach($GLOBALS['DATA']['e-time'] as $v) $t[] = "$v[msg]:$v[time]";
	}
	return implode(', ', $t);
}


error_reporting(E_ERROR | E_WARNING | E_PARSE);
//error_reporting(E_ALL ~(E_WARNING));
//error_reporting(0);

ob_start();

define('E', substr($_SERVER['SCRIPT_FILENAME'], 0, strripos($_SERVER['SCRIPT_FILENAME'],'/') + 1));

require_once '_lib/_const.php';
require_once '_lib/_auth.php';
require_once '_lib/_lib.php';

$dbReady = require_once '_lib/_db.php';

timesnap('db');

$META = array();
$SCRIPT = array('link' => array(), 'inline' => array(), 'tag' => array());
$HEAD = array('meta' => array(), 'ns' => array());
$STACK = array();
$SP = 0;

$p = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : 
	(isset($_SERVER['ORIG_PATH_INFO']) ? $_SERVER['ORIG_PATH_INFO'] : 
															$_SERVER['REQUEST_URI']);

require_once 'config.php';




// **************************************************************
// Convert URL to array of components and params
// Component like 'page-3' treats as param 'page' with value '3'
// Also detects 'date' and 'id'
// **************************************************************

function _parseURL($u) {
	global $DATA;

	$temp = array_trim_empty_str(explode('/', $u));
	$urllen = 0;
	$url = array(
		0 => array( 'path' => '', 'params' => array() ),
	);
	$lang = false;
	
	$langs = array_keys($DATA['langs']);

	foreach ($temp as $t) {
		if (!$urllen && in_array($t, $langs)) {	// manually detect languages
			$lang = $t;
			$url[$urllen++] = array('path' => $t, 'params' => array(), 'virtual' => 1);
		} else
		if (preg_match('/^(\d{2,4}-\d{1,2}-\d{1,2})$/', $t, $r)) {		// manually detect date in url
			$url[$urllen]['params']['date'] = $r[1];
		} else
		if (preg_match('/^(\d+)/', $t, $r)) {		// manually detect number in url. treate any string starting from digit as ID
			$url[$urllen]['params']['id'] = $r[1];
		} else
		if (preg_match('/([a-zA-Z_][a-zA-Z0-9_]*)-(.+)/', $t, $r)) {	
			$url[$urllen]['params'][$r[1]] = $r[2];
		} else {
			if (sizeof($url[$urllen]['params']) || $url[$urllen]['path']) $urllen++;
			$url[$urllen] = array('path' => $t, 'params' => array());
		}
	}
	
	return array('lang' => $lang, 'url' => $url);
}

function _createURL($url, $params = true) {
	$temp = '/';
	$anchor = '';
	
	foreach($url as $u) {
		if (substr($u['path'],0,1) == '#') {
			$anchor = $u['path'];
			continue;
		}

		$temp .= $u['path'].'/';
		
		if ($params) {
			$id = 0;
			foreach($u['params'] as $k => $v) {
				if ($k == 'id') {
					$id = $v;
					continue;
				} else {
					if (($k == '__raw') || ($k == 'date'))
					$temp .= "$v/";
				else
					$temp .= "$k-$v/";
	}
			}
			
			if ($id) {	// apply ID if exists
				if ((int)$id)
					$temp .= "$id/";
				else
					$temp .= "id-$id/";
			}
		
		}
	}
	return $temp.$anchor;
}

function _transformURL($url, $todo) {
	$params = true;
	
	foreach ($todo as $do => $param) {
		switch ($do) {
			case 'strip_params':
				$params = false;
				break;
			case 'remove_param':
				$elem = end(array_keys($url));
				unset($url[$elem]['params'][$param]);
				break;
			case 'remove_params':
				$elem = end(array_keys($url));
				if ($param == 'all') {
					$url[$elem]['params'] = array();
				} else if (sizeof($param = array_trim_empty_str(explode(',',$param)))) {
					foreach($param as $p)
						unset($url[$elem]['params'][$p]);
				}
				break;
			case 'add_param':
				$elem = end(array_keys($url));
				if (is_array($param))
					foreach ($param as $k => $v)
						$url[$elem]['params'][$k] = $v;
				else {
					list($k,$v) = explode(':',$param);
					$url[$elem]['params'][$k] = $v;
				}
				break;
			case 'add_raw':
				$elem = end(array_keys($url));
				$url[$elem]['params']['__raw'] = $param;
				break;
			case 'step_back':
				for (; $param; $param--) 
					if (sizeof($url))
						array_pop($url);
				break;
			case 'add_level':
				$url[] = array('path' => $param, 'params' => array());
				break;
			case 'add_anchor':
				$url[] = array('path' => '#'.$param, 'params' => array());
				break;			
			case 'replace_level':
				list($l,$v) = explode(':',$param);
				if ($l < 0) 
					$l = sizeof($url) + $l;
				$keys = array_keys($url);
				$elem = $keys[$l];
				if ($v) $url[$elem]['path'] = $v; else	unset($url[$elem]);
				break;
		}
	}

	return _createURL($url, $params);
}

function _completeURL($url) {	// replaces <tag> with context('tag')
	return preg_replace_callback('/(<\w+>)/', create_function('$m', 'return ($t = context(substr($m[1], 1, -1))) ? $t : $m[0];'), $url);
}

// **************************************************************

$CONTEXT = array(
	'template' => '',
	'css' => array(),
	'rawUrl' => $p,
	'format' => 'html',
);

$temp = _parseURL($p);
if ($temp['lang']) $CONTEXT['lang'] = $temp['lang'];
$CONTEXT['url'] = $temp = $temp['url'];

$CONTEXT['lang_prefix'] = $CONTEXT['lang'] ? (($CONTEXT['lang'] == LANG_DEF) ? '' : "$CONTEXT[lang]/") : ''; 
$CONTEXT['params'] = $temp[sizeof($temp)-1]['params'];

if ($dbReady) {

	if ($CURRENT = dataset('struct', $CONTEXT['url'], $CONTEXT['lang'] ? $CONTEXT['lang'] : LANG_DEF)) {
	
timesnap('struct');

		$CONTEXT['page'] = $DATA['page'] = $CURRENT->data[sizeof($CURRENT->data)-1]['struct'];		// page data from struct table
	
		if (
			($CONTEXT['isAdminPage'] = $DATA['page']['tag'] & $PRIV['admin']['mask']) && 
			 USE_HTTPS &&
			($_SERVER['HTTPS'] != 'on' )) {

			$new_url = "https://" . $_SERVER['SERVER_NAME'] . $CONTEXT['rawUrl'];
			header("Location: $new_url");
			exit();
		}
	
		loadPermissions();
	
		if (permitted('see-debug-output')) {
			if ($t = trim(ob_get_clean())) 
				print $t;
		} else ob_end_clean();
	
ob_start(); // ie7 script loading bugs runaround
	
		if (!isset($CONTEXT['lang']))	// check for admin area language
			$CONTEXT['lang'] = $CONTEXT['isAdminPage'] ? LANG_ADMIN : LANG_DEF;
	
		if (is_file("_lib/_lang.php")) {				// load global translation table
			require_once "_lib/_lang.php";
		}
		
		if ($temp = datafetch('meta', D_PAGENAMES, $DATA['page']['id'], $CONTEXT['lang'], 'name'))
			$DATA['page']['name'] = $temp;


		$DATA['ip'] = $_SERVER['REMOTE_ADDR'];
		if (isset ($_SERVER['HTTP_X_FORWARDED_FOR']) && ($_SERVER['HTTP_X_FORWARDED_FOR'] != $_SERVER['REMOTE_ADDR']))
			$DATA['ip'] .= '-'.$_SERVER['HTTP_X_FORWARDED_FOR'];

		
		switch ($CURRENT->kind & 0x0f) {
	
			case PK_REDIRECT:		// redirect this page to other
	
				header("Location: "._completeURL($CURRENT->template));
				exit;
				break;
	
			case PK_NOTFOUND:		// 404 page not found
				
				$temp = _parseURL($CONTEXT['rawUrl'] = '/');
				$CONTEXT['url'] = $temp['url'];
				
				header("HTTP/1.0 404 Not Found\n");

				if (USE_LOG4) {
					$log->info(implode(" ", array(
						"ip:$DATA[ip]", 
						"user:".logged_in(), 
						"page:{$DATA[page][id]}", 
						"url:".context('rawUrl'),
						"not found",
					)));
				}
	
			case PK_NORMAL:		// usual templated page
	
				if (isset($_POST['log_out'])) {		// if trying to logout

					if (USE_LOG4) {
						$log->warn(implode(" ", array(
							"logout",
							"ip:$DATA[ip]", 
							"user:".user_info('id'), 
							"name:".user_info('name'),
						)));
					}

					unset($_SESSION['user']);
					create_session();
					header("Location: ./\n");
					exit;
				}
				
				if (isset($_POST['log_in'])) {		// if trying to login
					include '_lib/_login.php';
					header("Location: ./\n");
					exit;
				}
	
	
				$DATA['crumb'] = getCrumb($CURRENT->data);
				
				$META = datafetch_array('meta', D_META, dat('page','id'));							// page metadata (body_id, page_title etc.)
	
				if (permitted('page-access')) {
	
					$CONTEXT['template'] = $CURRENT->template;
		
					while (true) {
						if (is_file("_template/{$CONTEXT[template]}/router.php")) {				// template routing
							$temp = include "_template/{$CONTEXT[template]}/router.php";
							if ($temp && is_dir("_template/$temp")) {		// route to somewhere
								if ($CONTEXT['template'] != $temp) {		// new route - let's check it
									$CONTEXT['template'] = $temp;
									continue;
								} else break;	// the same route, go on
							} else break;		// invalid route
						} else break;			// no route found
					}
		
					if ($CURRENT->kind & PK_XML) {
						$CONTEXT['format'] = 'xml';
						header("Content-Type: text/xml\n");
					}
	
				} else
					$CONTEXT['template'] = PK_LOGIN_TEMPLATE;
	
				if (!($DATA['sitewide'] = mc("engine.sitewide.".context('lang')))) {
					$DATA['sitewide'] = datafetch_array('meta', D_SITEWIDE, 0, context('lang'));	// site metadata 
					
					mcSet("engine.sitewide.".context('lang'), $DATA['sitewide'], MC_EXPIRE - mt_rand(2*60, 7*60));
				}
	
				$BITS = array_unique(array_trim_empty_str(array_merge(explode(',', config('bits','')), explode(',', meta('bits','')))));
				if ($b = bits('init', 'user')) foreach($b as $bit) { include bit($bit); }

timesnap('gen');

	if (USE_LOG4 && context('isAdminPage')) {
		$log->info(implode(" ", array(
			"ip:$DATA[ip]", 
			"user:".logged_in(), 
			"permitted:".(permitted('page-access') ? 'yes' : 'no'),
			"page:{$DATA[page][id]}", 
			"url:".context('rawUrl'),
			"name:".implode(':', array_merge(createTitle(), array($DATA['page']['name']))),
		)));
	}

	
				if (is_file("_template/{$CONTEXT[template]}/init.php")) {							// template initialization
					include "_template/{$CONTEXT[template]}/init.php";
				}
	
				if (is_file("_template/{$CONTEXT[template]}/lang-{$CONTEXT[lang]}.php")) {		// template localization
					include "_template/{$CONTEXT[template]}/lang-{$CONTEXT[lang]}.php";
				}
	
				$t = ($x = $DATA['sitewide']['title']) ? $x : xmeta('site-name');//sta('project','name');
				$DATA['title'] = array_merge(array($t), createTitle());
	
				if (is_file("_template/{$CONTEXT[template]}/show.php")) {							// template itself
					include "_template/{$CONTEXT[template]}/show.php";
				}
					else print("<p>Something went wrong.<br>Can't access the \"{$CONTEXT[template]}\" template.</p><p>Please press \"Back\" button or go to the <a href='/'>Start</a> page.</p>");
				
				break;
	
			default:
				debug($CONTEXT, "CONTEXT");
				debug($CURRENT, "CURRENT");
				debug($STATIC, "STATIC");
	
				break;
		}
	
	
	} else {
	
		print("Something went wrong.<br>Can't access the site structure.<br><p>Please come back later.</p>");
	
	}

} else {
	$CONTEXT['template'] = PK_NODB_TEMPLATE;
	$CONTEXT['lang'] = LANG_DEF;
	
	if (is_file("_template/{$CONTEXT[template]}/init.php")) {							// template initialization
		include "_template/{$CONTEXT[template]}/init.php";
	}

	if (is_file("_template/{$CONTEXT[template]}/lang-{$CONTEXT[lang]}.php")) {		// template localization
		include "_template/{$CONTEXT[template]}/lang-{$CONTEXT[lang]}.php";
	}

	if (is_file("_template/{$CONTEXT[template]}/show.php")) {							// template itself
		include "_template/{$CONTEXT[template]}/show.php";
	}
}